SPDX-FileCopyrightText: 2018 Marion Vancoppenolle & Natalia Casas SPDX-FileCopyrightText: 2024 AlICe laboratory https://alicelab.be
SPDX-License-Identifier: GPL-3.0-or-later
Sol Lewitt project Casas Natalia et Vancoppenolle Marion
import bpy
import random
import mathSupprimer de manière récurrente
from bpy import data as Ddef delete_all():
    for item in D.objects:
        D.objects.remove(item)
    for item in D.meshes:
        D.meshes.remove(item)
delete_all()def lshape(_position, _type, _nom):création du cube de base
    bpy.ops.mesh.primitive_cube_add(radius=0.5, location=_position)
    bpy.context.object.name = _nom
    cube = bpy.data.objects[_nom]Biseau sur les coins de la forme
    bevelMod = cube.modifiers.new("MyBevel", "BEVEL")
    bevelMod.width = 0.05Création du cube qui servira pour Boolean différence
    bpy.ops.mesh.primitive_cube_add(
        radius=0.5,
        location=(_position[0] + 0.2, _position[1] + 0.2, _position[2] + 0.2),
    )
    bpy.context.object.name = "CubeToDelete"
    cubeToDelete = bpy.data.objects["CubeToDelete"]
    bpy.context.scene.objects.active = cubeBoolean Difference
    extrudeCube = cube.modifiers.new("MyExtrudeCube", "BOOLEAN")
    extrudeCube.operation = "DIFFERENCE"
    extrudeCube.object = cubeToDelete
    bpy.ops.object.modifier_apply(apply_as="DATA", modifier="MyExtrudeCube")
    bpy.context.scene.objects.active = cubeToDelete
    bpy.ops.object.delete(use_global=False)rotation de l’élement de base afin de créer 8 élément différents
    if _type == 0:
        _rotation = (0, 0, 0)
    if _type == 1:
        _rotation = (math.pi / 2, 0, 0)
    if _type == 2:
        _rotation = (0, math.pi / 2, 0)
    if _type == 3:
        _rotation = (0, 0, math.pi)
    if _type == 4:
        _rotation = (math.pi / 2, math.pi, -math.pi / 2)
    if _type == 5:
        _rotation = (0, math.pi, math.pi / 2)
    if _type == 6:
        _rotation = (math.pi / 2, math.pi, 0)
    if _type == 7:
        _rotation = (math.pi / 2, math.pi, math.pi / 2)
    cube.rotation_euler = _rotationcréation d’une fonction qui permettra de supprimer un élément dans une liste donnée
def getNextDel(val, order, dimension, list):
    if val == -1:
        val = random.randint(
            0, len(list) - 1
        )  # Variante de suppression:permet que ce ne soit pas toujours les mêmes qui restent
    else:
        if order == 0:
            if val >= len(list):
                val = 0
        else:
            val = val - 1
            if val < 0:
                val = len(list) - 1
    return valcréer l’objet principal
def building(
    dimension,
):  # dimension : base cubique de dimension 2x2 (éléments) ou 3x3 ou 4x4 ou plus
    l = []Point de départ : introduire un ordre de suppression, (un voisin doit toujours etre supprimé) possible autant avec une base cubique de 2x2 que 3x3
    if dimension % 2 == 0:
        x = dimension / 2 - 1
        y = dimension / 2 - 1
    else:
        x = (dimension - 1) / 2
        y = (
            dimension - 1
        ) / 2  # On a 2 possibilité de sens : les nombres paires et les impaires
    for i in range(0, dimension * dimension):
        l.append((x - ((dimension - 1) / 2), y - ((dimension - 1) / 2)))
        print("(" + str(x) + "," + str(y) + ")")
        if dimension % 2 == 0:  # nombres paires
            if x == y and x > dimension / 2 - 1:
                xNew = -1
                yNew = 0
            elif x == y and x <= dimension / 2 - 1:
                xNew = +1
                yNew = 0
            elif x > dimension / 2 - 1 and (x + y) == dimension - 1:
                xNew = 0
                yNew = +1
            elif x < dimension / 2 - 1 and x + y == dimension - 2:
                xNew = 0
                yNew = -14 éléments max par couche: 4 possibilités disposition des 4éléments par rapport au socle cubique
        else:  # nombres impaires
            if x == y and x > (dimension - 1) / 2:
                xNew = -1
                yNew = 0
            elif x == y and x <= (dimension - 1) / 2:
                xNew = +1
                yNew = 0
            elif x > (dimension - 1) / 2 and (x + y) == dimension:
                xNew = 0
                yNew = +1
            elif x < ((dimension - 1) / 2) and x + y == dimension - 1:
                xNew = 0
                yNew = -14 éléments max par couche: 4 possibilités disposition des 4éléments par rapport au socle cubique
        x = x + xNew
        y = y + yNew  # position par rapport au socle
    l1 = l[:]  # listes de chaque direction
    l2 = l[:]
    l3 = l[:]
    l4 = l[:]
    l5 = l[:]
    l6 = l[:]
    print(l)socle cubique central
    for couche in range(0, dimension):
        i = 0
        for coord in l:
            lshape(
                (*coord, -((dimension - 1) / 2) + couche),
                random.randint(0, 7),
                "socle_" + str(couche) + "_" + str(i),
            )
            i = i + 1AXE X
Un des deux cotés sur l’axe des x peut être diminué-tronqué
    SensTronque = random.randint(0, 1)
    if SensTronque == 0:
        nbcouches1 = random.randint(0, dimension * dimension - 1)
        nbcouches2 = dimension * dimension - 1
    else:
        nbcouches1 = dimension * dimension - 1
        nbcouches2 = random.randint(
            0, dimension * dimension - 1
        )  # si l'un des 2 est 'coupé', l' autre va automatiuement jusu'au boutaxe x gauche
    OrderDel = random.randint(
        0, 1
    )  # suppression d'un élément au hasard au fur et à mesure des couches
    NextDel = -1
    for couche in range(0, nbcouches1):
        NextDel = getNextDel(
            NextDel, OrderDel, dimension, l1
        )  # ordre de suppression: on garde une progressionl1: fait référence au sens créé plus tot
        del l1[NextDel]  # suppression définitive
        i = 0
        for coord in l1:
            lshape(
                (-couche - ((dimension + 1) / 2), coord[0], coord[1]),
                random.randint(0, 7),
                "XGauche_" + str(couche) + "_" + str(i),
            )
            i = (
                i + 1
            )  # la branche de l'axe x qui tire vers la gauche est disposée contre le socle cubique et chaque élément est disposé au hasardaxe x droite
    OrderDel = random.randint(
        0, 1
    )  # suppression d'un élément au hasard au fur et à mesure des couches
    NextDel = -1
    for couche in range(0, nbcouches2):
        NextDel = getNextDel(
            NextDel, OrderDel, dimension, l2
        )  # ordre de suppression: on garde une progression
        del l2[
            NextDel
        ]  # suppression définitive                    # l2: fait référence au sens créé plus tot
        i = 0
        for coord in l2:
            lshape(
                (couche + ((dimension + 1) / 2), coord[0], coord[1]),
                random.randint(0, 7),
                "XDroite_" + str(couche) + "_" + str(i),
            )
            i = (
                i + 1
            )  # la branche de l'axe x qui tire vers la droite est disposée contre le socle cubique et chaque élément est disposé au hasardAXE Y
Un des deux cotés sur l’axe des x peut être diminué-tronqué
    if SensTronque == 0:
        nbcouches1 = random.randint(0, dimension * dimension - 1)
        nbcouches2 = dimension * dimension - 1
    else:
        nbcouches1 = dimension * dimension - 1
        nbcouches2 = random.randint(
            0, dimension * dimension - 1
        )  # si l'un des 2 est 'coupé', l' autre va automatiuement jusu'au boutaxe y arrière
    OrderDel = random.randint(
        0, 1
    )  # suppression d'un élément au hasard au fur et à mesure des couches
    NextDel = -1
    for couche in range(0, nbcouches1):
        NextDel = getNextDel(
            NextDel, OrderDel, dimension, l3
        )  # ordre de suppression: on garde une progression
        del l3[NextDel]
        i = 0
        for coord in l3:
            lshape(
                (coord[1], -couche - ((dimension + 1) / 2), coord[0]),
                random.randint(0, 7),
                "YArriere_" + str(couche) + "_" + str(i),
            )
            i = i + 1axe y avant
    OrderDel = random.randint(
        0, 1
    )  # suppression d'un élément au hasard au fur et à mesure des couches
    NextDel = -1
    for couche in range(0, nbcouches2):
        NextDel = getNextDel(
            NextDel, OrderDel, dimension, l4
        )  # ordre de suppression: on garde une progression
        i = 0
        for coord in l4:
            lshape(
                (coord[0], couche + ((dimension + 1) / 2), coord[1]),
                random.randint(0, 7),
                "YAvant_" + str(couche) + "_" + str(i),
            )
            i = i + 1AXE Z
Un des deux cotés sur l’axe des x peut être diminué-tronqué
    if SensTronque == 0:
        nbcouches1 = random.randint(0, dimension * dimension - 1)
        nbcouches2 = dimension * dimension - 1
    else:
        nbcouches1 = dimension * dimension - 1
        nbcouches2 = random.randint(
            0, dimension * dimension - 1
        )  # si l'un des 2 est 'coupé', l' autre va automatiuement jusqu'au bout (jusqu'à la couche où il ne reste qu'un seul élément)axe z haut
    OrderDel = random.randint(
        0, 1
    )  # suppression d'un élément au hasard au fur et à mesure des couches
    NextDel = -1
    for couche in range(0, nbcouches1):
        NextDel = getNextDel(
            NextDel, OrderDel, dimension, l5
        )  # ordre de suppression: on garde une progression
        del l5[NextDel]
        i = 0
        for coord in l5:
            lshape(
                (coord[0], coord[1], couche + ((dimension + 1) / 2)),
                random.randint(0, 7),
                "ZHaut_" + str(couche) + "_" + str(i),
            )
            i = (
                i + 1
            )  # la branche de l'axe de z qui tire vers le haut est disposé contre le socle cubique et chaque élément est disposé au hasardaxe z Bas
    OrderDel = random.randint(
        0, 1
    )  # suppression d'un élément au hasard au fur et à mesure des couches
    NextDel = -1
    for couche in range(0, nbcouches2):
        NextDel = getNextDel(
            NextDel, OrderDel, dimension, l6
        )  # ordre de suppression: on garde une progression
        del l6[NextDel]
        i = 0
        for coord in l6:
            lshape(
                (coord[0], coord[1], -couche - ((dimension + 1) / 2)),
                random.randint(0, 7),
                "ZBas_" + str(couche) + "_" + str(i),
            )
            i = i + 1
building(2)  # dimension : base cubique de 2x2 ou 3x3 ou 4x4 ou plus